package com.ibix.util;

import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 项目名称：CaiHai
 * <br>类描述：
 * <br>创建人：htliu
 * <br>创建时间：2017/9/19 13:25
 * <br>修改人:
 * <br>修改时间：2017/9/19 13:25
 * <br>修改备注：
 * <br>@version
 */
@Component
public class JWT {
    private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545fdf>?N<:{LWPW";

    private static final String EXP = "exp";

    private static final String PAYLOAD = "payload";

    @Value("${config.token.expire}")
    private long expire;

    private ObjectMapper mapper = new ObjectMapper();

    private JWTVerifier verifier = new JWTVerifier(SECRET);


    public <T> String sign(T object) {
        return sign(object, expire);
    }

    /**
     * 加密，传入一个对象和有效期
     *
     * @param object
     * @param maxAge
     * @param <T>
     * @return
     */
    public <T> String sign(T object, long maxAge) {
        if (object == null) {
            return "";
        }
        try {
            final JWTSigner signer = new JWTSigner(SECRET);
            final Map<String, Object> claims = new HashMap<String, Object>(2);
            String jsonString = mapper.writeValueAsString(object);
            claims.put(PAYLOAD, jsonString);
            claims.put(EXP, System.currentTimeMillis() + maxAge);
            return signer.sign(claims);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 解密，传入一个加密后的token字符串和解密后的类型
     *
     * @param jwt
     * @param classT
     * @param <T>
     * @return
     */
    public <T> T unSign(String jwt, Class<T> classT) {
        if (StringUtils.isEmpty(jwt)) {
            return null;
        }
        try {
            final Map<String, Object> claims = verifier.verify(jwt);
            if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
                long exp = (Long) claims.get(EXP);
                long currentTimeMillis = System.currentTimeMillis();
                if (exp > currentTimeMillis) {
                    String json = (String) claims.get(PAYLOAD);
                    return mapper.readValue(json, classT);
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

}
